package test;

import Protocol.*;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Client {
	
    private PrintWriter printWriter;
    private ObjectOutputStream objectOutputStream;
    private ObjectInputStream objectInputStream;
    
    public Client(String internetAddres, int portnumber) {
        Socket socket = createSocketConnection(internetAddres, portnumber);
        System.out.println("Created Socket Connection");
        InputStream inputStream = createInputStream(socket);
        System.out.println("Created InputStream");
        OutputStream outputStream = createOutputStream(socket);
        System.out.println("Created outputstream");
        createPrintWriter(outputStream);
        System.out.println("Created printwriter");
        createBufferReader(socket);
        System.out.println("Created bufferreader");
        
        createObjectOutputStream(outputStream);
        System.out.println("Created objectoutputstream");
        createObjectInputStream(inputStream);
        System.out.println("Created objectinputstream");
    }
    
    private Socket createSocketConnection(String internetAddres, int portnumber) {
        Socket socket = null;
        try {
            socket = new Socket(internetAddres, portnumber);
            
            
        } catch (UnknownHostException e) {
            System.out.println("Unknown host: " + internetAddres);
            System.exit(1);
        } catch (IOException e) {
            System.out.println("No I/O");
            System.exit(1);
        }
        return socket;
    }
    
    private InputStream createInputStream(Socket socket) {
        InputStream inputStream = null;
        try {
            inputStream = socket.getInputStream();
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
        return inputStream;
    }
    
    private BufferedReader createBufferReader(Socket socket) {
        BufferedReader bufferedReader = null;
        try {
            bufferedReader =
                    new BufferedReader(new InputStreamReader(socket.getInputStream()));
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return bufferedReader;
    }
    
    private OutputStream createOutputStream(Socket socket) {
        OutputStream outputStream = null;
        try {
            outputStream = socket.getOutputStream();
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
        return outputStream;
    }
    
    private PrintWriter createPrintWriter(OutputStream outputStream) {
        printWriter = new PrintWriter(outputStream, true);
        return printWriter;
    }
    
    private ObjectInputStream createObjectInputStream(InputStream inputStream) {
        objectInputStream = null;
        try {
            objectInputStream = new ObjectInputStream(inputStream);
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return objectInputStream;
    }
    
    private ObjectOutputStream createObjectOutputStream(OutputStream outputStream) {
        objectOutputStream = null;
        try {
            objectOutputStream = new ObjectOutputStream(outputStream);
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
        return objectOutputStream;
    }
    
    public void sendProtocolMessage(String message) {
        TestPacket packetToSend = (TestPacket) PacketFactory.getPacket(PacketTypeKeeper.TESTPACKET);
        packetToSend.setMessage(message);
        System.out.println(packetToSend);
        
        System.out.println(">> " + packetToSend.getMessage());
        try {
            this.objectOutputStream.writeObject(packetToSend);
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void sendPlainMessage(String message) {
        this.printWriter.println(message);
        System.out.println(">>> " + message);
    }
    
    public String readProtocolMessage() {
        String message = null;
        try {
            TestPacket incomingObject = (TestPacket) objectInputStream.readObject();
            message = incomingObject.getMessage();
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
        return message;
    }
    
    public void sendProtocolMessage(BasicPacket packetToSend) {
        try {
            this.objectOutputStream.writeObject(packetToSend);
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void sendInlogRequestAsUser() {
        InlogRequestPacket irp =
                (InlogRequestPacket) PacketFactory.getPacket(PacketTypeKeeper.INLOGREQUESTPACKET);
        irp.setUsername("Tester John");
        irp.setPassword("John Pass");
        irp.setTypeOfClient(PacketTypeKeeper.USER);
        
        sendProtocolMessage(irp);
    }
    
    public void sendInlogRequestAsAdmin() {
        InlogRequestPacket irp =
                (InlogRequestPacket) PacketFactory.getPacket(PacketTypeKeeper.INLOGREQUESTPACKET);
        irp.setUsername("Tester Johhn");
        irp.setPassword("John Pass");
        irp.setTypeOfClient(PacketTypeKeeper.ADMIN);
        
        sendProtocolMessage(irp);
    }
    
    private void print(String message) {
        System.out.println(message);
    }
    
    private void print(int message) {
        System.out.println(message + "");
    }
    
    public void sendAcciniReq() {
        AccountManagementRequestPacket amrp = new AccountManagementRequestPacket(1);
        amrp.setTypeOfManagementPacket(PacketTypeKeeper.INITIAL);
        
        System.out.println(amrp.getAccountInformation() + "type:" + amrp.getTypeOfManagementPacket());
        
        sendProtocolMessage(amrp);
    }
    
    public void sendAccAddReq() {
        AccountManagementRequestPacket amrp = new AccountManagementRequestPacket(1);
        amrp.setTypeOfManagementPacket(PacketTypeKeeper.ADDACCOUNT);
        amrp.setAccountInformation("testWinId", "testName", "testPass", "1");
        
        System.out.println(amrp.getAccountInformation() + "type:" + amrp.getTypeOfManagementPacket());
        
        sendProtocolMessage(amrp);
    }
    
    public void sendAlterAccReq1() {
        AccountManagementRequestPacket amrp = new AccountManagementRequestPacket(1);
        amrp.setTypeOfManagementPacket(PacketTypeKeeper.ALTERACCOUNT);
        amrp.setAccountInformation("testWinId", "testName", "testPass", "1");
        amrp.setAlterAccountToo("myTestWinId", "myTestUser", "myTestPass", "0");
        
        System.out.println(amrp.getAccountInformation() + "type:" + amrp.getTypeOfManagementPacket());
        System.out.println(amrp.getAlterAccountToo());
        
        sendProtocolMessage(amrp);
    }
    
    public void sendAlterAccReq2() {
        AccountManagementRequestPacket amrp = new AccountManagementRequestPacket(1);
        amrp.setTypeOfManagementPacket(PacketTypeKeeper.ALTERACCOUNT);
        amrp.setAlterAccountToo("testWinId", "testName", "testPass", "1");
        amrp.setAccountInformation("myTestWinId", "myTestUser", "myTestPass", "0");
        
        System.out.println(amrp.getAccountInformation() + "type:" + amrp.getTypeOfManagementPacket());
        System.out.println(amrp.getAlterAccountToo());
        
        sendProtocolMessage(amrp);
    }
    public void sendQueryRequest(){
        QueryRequestPacket qrp = (QueryRequestPacket) PacketFactory.getPacket(PacketTypeKeeper.QUERYREQUESTPACKET);
        qrp.setQuery("SELECT * FROM [dbo].[CRONUS Nederland BV$Job]");
        qrp.setQueryName("JOBBSssssssS");
        qrp.setQueryId(4);
        qrp.setStatus(QueryRequestPacket.UPDATE);
        
         QueryRequestPacket qrp1 = (QueryRequestPacket) PacketFactory.getPacket(PacketTypeKeeper.QUERYREQUESTPACKET);
        qrp1.setQuery("SELECT * FROM [dbo].[CRONUS Nederland BV$Sales Header]");
        qrp1.setQueryName("Patrick");
        //qrp1.setQueryId(5);
        qrp1.setStatus(QueryRequestPacket.INSERT);
        
        sendProtocolMessage(qrp);
        sendProtocolMessage(qrp1);
        
    }
    public void sendDelAccReq() {
        AccountManagementRequestPacket amrp = new AccountManagementRequestPacket(1);
        amrp.setTypeOfManagementPacket(PacketTypeKeeper.DELETEACCOUNT);
        amrp.setAccountInformation("testWinId", "testName", "testPass", "1");
        
        System.out.println(amrp.getAccountInformation() + "type:" + amrp.getTypeOfManagementPacket());
        sendProtocolMessage(amrp);
    }
    
    private void printTable(ArrayList<String[]> list) {
        System.out.println("printing table");
        for (String[] row : list) {
            for (int i = 0; i < row.length; i++) {
                System.out.println(row[i] + "\t");
            }
            System.out.println();
        }
    }
}
